package com.ruoyi.car.business.service.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import com.ruoyi.car.business.domain.BusBpmnInfo;
import com.ruoyi.car.business.mapper.BusBpmnInfoMapper;
import com.ruoyi.car.business.service.IBusBpmnInfoService;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.exception.business.BusinessException;
import com.ruoyi.common.utils.file.FileUploadUtils;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.image.ProcessDiagramGenerator;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.common.core.text.Convert;
import org.springframework.web.multipart.MultipartFile;

/**
 * 流程定义明细Service业务层处理
 * 
 * @author ruoyi
 * @date 2022-02-03
 */
@Service
public class BusBpmnInfoServiceImpl implements IBusBpmnInfoService
{
    @Autowired
    private BusBpmnInfoMapper busBpmnInfoMapper;
    @Autowired
    private RepositoryService repositoryService;

    /**
     * 查询流程定义明细
     * 
     * @param id 流程定义明细主键
     * @return 流程定义明细
     */
    @Override
    public BusBpmnInfo selectBusBpmnInfoById(Long id)
    {
        return busBpmnInfoMapper.selectBusBpmnInfoById(id);
    }

    /**
     * 查询流程定义明细列表
     * 
     * @param busBpmnInfo 流程定义明细
     * @return 流程定义明细
     */
    @Override
    public List<BusBpmnInfo> selectBusBpmnInfoList(BusBpmnInfo busBpmnInfo)
    {
        return busBpmnInfoMapper.selectBusBpmnInfoList(busBpmnInfo);
    }

    /**
     * 新增流程定义明细
     * 
     * @param busBpmnInfo 流程定义明细
     * @return 结果
     */
    @Override
    public int insertBusBpmnInfo(BusBpmnInfo busBpmnInfo)
    {
        return busBpmnInfoMapper.insertBusBpmnInfo(busBpmnInfo);
    }

    /**
     * 修改流程定义明细
     * 
     * @param busBpmnInfo 流程定义明细
     * @return 结果
     */
    @Override
    public int updateBusBpmnInfo(BusBpmnInfo busBpmnInfo)
    {
        return busBpmnInfoMapper.updateBusBpmnInfo(busBpmnInfo);
    }

    /**
     * 批量删除流程定义明细
     * 
     * @param ids 需要删除的流程定义明细主键
     * @return 结果
     */
    @Override
    public int deleteBusBpmnInfoByIds(String ids)
    {
        return busBpmnInfoMapper.deleteBusBpmnInfoByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除流程定义明细信息
     * 
     * @param id 流程定义明细主键
     * @return 结果
     */
    @Override
    public void deleteBusBpmnInfoById(Long id)
    {
        BusBpmnInfo bpmnInfo = busBpmnInfoMapper.selectBusBpmnInfoById(id);
        String deploymentId = bpmnInfo.getDeploymentId();
        // TODO 查询所有的流程实例,找到业务标识,更新业务标识信息
        // 删除bpmnInfo
        busBpmnInfoMapper.deleteBusBpmnInfoById(id);
        // 把部署文件删除
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .deploymentId(deploymentId)
                .singleResult();
        // 删除流程定义
        repositoryService.deleteDeployment(deploymentId, true);
        String resourceName = processDefinition.getResourceName();
        File file = new File(RuoYiConfig.getProfile(), resourceName);
        if (file.exists()) {
            file.delete();
        }
    }

    /**
     * 流程文件部署
     * @param path
     * @param bpmnType
     * @param info
     * @throws IOException
     */
    @Override
    public void deploy(String path, String bpmnType, String info) throws IOException {
        // 获取之前上传的文件
        File bpmn = new File(RuoYiConfig.getProfile(), path);
        FileInputStream inputStream = new FileInputStream(bpmn);
        // 将文件部署到Activiti7中
        Deployment deploy = repositoryService.createDeployment()
                .addInputStream(path, inputStream)
                .deploy();
        // 释放资源
        inputStream.close();
        // 封装BpmnInfo的信息
        BusBpmnInfo bpmnInfo = new BusBpmnInfo();
        bpmnInfo.setDeployTime(new Date());
        bpmnInfo.setInfo(info);
        bpmnInfo.setBpmnType(bpmnType); // 审核类型,数据字典的值
        bpmnInfo.setDeploymentId(deploy.getId()); // 部署id
        // 获取流程定义
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .deploymentId(deploy.getId())
                .singleResult();
        bpmnInfo.setActProcessId(processDefinition.getId());
        bpmnInfo.setActProcessKey(processDefinition.getKey());
        busBpmnInfoMapper.insertBusBpmnInfo(bpmnInfo);
    }

    /**
     * 部署文件上传
     * @param file
     * @return
     * @throws IOException
     */
    @Override
    public String upload(MultipartFile file) throws IOException {
        String extension = FileUploadUtils.getExtension(file);
        if (!"bpmn".equalsIgnoreCase(extension)) {
            throw new BusinessException("只能上传bpmn格式的文件");
        }
        // 在配置文件中配置的文件上传路径system.car.profile
        // (项目最终部署的时候会打包成jar,将上传的文件存储到磁盘目录中)
        String filePath = FileUploadUtils.upload(RuoYiConfig.getProfile(), file);
        String filePath2 = filePath.replaceAll("/profile", "");
        System.out.println(filePath2);
        return filePath2;
    }

    /**
     * 查看资源
     */
    @Override
    public InputStream getFileInputStream(String deploymentId, String type) {
        InputStream inputStream = null;
        // 获取流程定义
        ProcessDefinition definition = repositoryService.createProcessDefinitionQuery()
                .deploymentId(deploymentId).singleResult();
        if ("xml".equalsIgnoreCase(type)) {
            // 获取xml的文件
            String resourceName = definition.getResourceName();
            return repositoryService.getResourceAsStream(deploymentId, resourceName);
        } else {
            BpmnModel model = repositoryService.getBpmnModel(definition.getId());
            // 获取png的文件
            ProcessDiagramGenerator generator = new DefaultProcessDiagramGenerator();
            //generateDiagram(流程模型,需要高亮的节点id的集合,需要高亮的线条,后面三个参数都表示是字体)
            inputStream = generator.generateDiagram(model,
                    Collections.EMPTY_LIST,
                    Collections.EMPTY_LIST,
                    "宋体",// 节点
                    "宋体",  // 文本
                    "宋体" // 注解
            );
        }
        return inputStream;
    }

    @Override
    public BusBpmnInfo getByBpmnType(String bpmnType) {
        return busBpmnInfoMapper.getByBpmnType(bpmnType);
    }
}
